package quick.frame.core.app;

import android.app.Activity;
import android.os.Handler;
import android.support.annotation.NonNull;

import com.elvishew.xlog.LogConfiguration;
import com.elvishew.xlog.LogLevel;
import com.elvishew.xlog.XLog;
import com.elvishew.xlog.flattener.DefaultFlattener;
import com.elvishew.xlog.printer.AndroidPrinter;
import com.elvishew.xlog.printer.ConsolePrinter;
import com.elvishew.xlog.printer.Printer;
import com.elvishew.xlog.printer.file.FilePrinter;
import com.elvishew.xlog.printer.file.backup.NeverBackupStrategy;
import com.elvishew.xlog.printer.file.naming.DateFileNameGenerator;

import java.util.ArrayList;
import java.util.HashMap;

import okhttp3.Interceptor;
import quick.frame.core.util.file.FileUtil;

/**
 * Created by liuyang
 */

public final class Configurator {

    private static final HashMap<Object, Object> QUICK_CONFIGS = new HashMap<>();
    private static final Handler HANDLER = new Handler();
    //private static final ArrayList<IconFontDescriptor> ICONS = new ArrayList<>();
    private static final ArrayList<Interceptor> INTERCEPTORS = new ArrayList<>();


    private Configurator() {

        QUICK_CONFIGS.put(ConfigKeys.CONFIG_READY, false);
        QUICK_CONFIGS.put(ConfigKeys.HANDLER, HANDLER);

    }

    public static Configurator getInstance() {
        return Holder.INSTANCE;
    }

    final HashMap<Object, Object> getQuickConfigs() {
        return QUICK_CONFIGS;
    }

    private static class Holder {
        private static final Configurator INSTANCE = new Configurator();
    }

    public final void configure() {
      //  initIcons();
       // Logger.addLogAdapter(new AndroidLogAdapter());
        QUICK_CONFIGS.put(ConfigKeys.CONFIG_READY, true);
        // 支持写入日志到文件
        //BuildConfig.DEBUG ? LogLevel.ALL : LogLevel.NONE            // 指定日志级别，低于该级别的日志将不会被打印，默认为 LogLevel.ALL

        //String path = this.getExternalFilesDir() + File.separator+"移动SPD"+ File.separator+"logs"+File.separator;
        LogConfiguration config = new LogConfiguration.Builder()
                .logLevel(LogLevel.DEBUG)
                .tag("SPD")                                         // 指定 TAG，默认为 "X-LOG"
                //.t()                                                   // 允许打印线程信息，默认禁止
                .st(2)                                                 // 允许打印深度为2的调用栈信息，默认禁止
                //.b()                                                   // 允许打印日志边框，默认禁止
                //.jsonFormatter(new MyJsonFormatter())                  // 指定 JSON 格式化器，默认为 DefaultJsonFormatter
                //.xmlFormatter(new MyXmlFormatter())                    // 指定 XML 格式化器，默认为 DefaultXmlFormatter
                //.throwableFormatter(new MyThrowableFormatter())        // 指定可抛出异常格式化器，默认为 DefaultThrowableFormatter
                //.threadFormatter(new MyThreadFormatter())              // 指定线程信息格式化器，默认为 DefaultThreadFormatter
                //.stackTraceFormatter(new MyStackTraceFormatter())      // 指定调用栈信息格式化器，默认为 DefaultStackTraceFormatter
                //.borderFormatter(new MyBoardFormatter())               // 指定边框格式化器，默认为 DefaultBorderFormatter
                //.addObjectFormatter(AnyClass.class,                    // 为指定类添加格式化器
                //		new AnyClassObjectFormatter())                     // 默认使用 Object.toString()
                //.addInterceptor(new BlacklistTagsFilterInterceptor(    // 添加黑名单 TAG 过滤器
                //		"blacklist1", "blacklist2", "blacklist3"))
                //.addInterceptor(new MyInterceptor())                   // 添加一个日志拦截器
                .build();

        Printer androidPrinter = new AndroidPrinter();             // 通过 android.util.Log 打印日志的打印器
        Printer consolePrinter = new ConsolePrinter();             // 通过 System.out 打印日志到控制台的打印器
        Printer filePrinter = new FilePrinter                      // 打印日志到文件的打印器
                .Builder(FileUtil.LOG_DIR)                              // 指定保存日志文件的路径
                .fileNameGenerator(new DateFileNameGenerator())        // 指定日志文件名生成器，默认为 ChangelessFileNameGenerator("log")
                .backupStrategy(new NeverBackupStrategy())             // 指定日志文件备份策略，默认为 FileSizeBackupStrategy(1024 * 1024)
                .logFlattener(new DefaultFlattener())                       // 指定日志平铺器，默认为 DefaultFlattener
                .build();

        XLog.init(                                                 // 初始化 XLog
                config,                                                // 指定日志配置，如果不指定，会默认使用 new LogConfiguration.Builder().build()
                androidPrinter,                                        // 添加任意多的打印器。如果没有添加任何打印器，会默认使用 AndroidPrinter(Android)/ConsolePrinter(java)
                consolePrinter,
                filePrinter);

    }

    public final Configurator withApiHost(String host) {
        QUICK_CONFIGS.put(ConfigKeys.API_HOST, host);
        return this;
    }

    public final Configurator withLoaderDelayed(long delayed) {
        QUICK_CONFIGS.put(ConfigKeys.LOADER_DELAYED, delayed);
        return this;
    }

   /* private void initIcons() {
        if (ICONS.size() > 0) {
            final Iconify.IconifyInitializer initializer = Iconify.with(ICONS.get(0));
            for (int i = 1; i < ICONS.size(); i++) {
                initializer.with(ICONS.get(i));
            }
        }
    }*/

   /* public final Configurator withIcon(IconFontDescriptor descriptor) {
        ICONS.add(descriptor);
        return this;
    }*/

    /**
     * 配置拦截器
     * @param interceptor 拦截器
     * @return 配置信息
     */
    public final Configurator withInterceptor(Interceptor interceptor) {
        INTERCEPTORS.add(interceptor);
        QUICK_CONFIGS.put(ConfigKeys.INTERCEPTOR, INTERCEPTORS);
        return this;
    }
    public final Configurator withInterceptors(ArrayList<Interceptor> interceptors) {
        INTERCEPTORS.addAll(interceptors);
        QUICK_CONFIGS.put(ConfigKeys.INTERCEPTOR, INTERCEPTORS);
        return this;
    }

    public final Configurator withWeChatAppId(String appId) {
        QUICK_CONFIGS.put(ConfigKeys.WE_CHAT_APP_ID, appId);
        return this;
    }

    public final Configurator withWeChatAppSecret(String appSecret) {
        QUICK_CONFIGS.put(ConfigKeys.WE_CHAT_APP_SECRET, appSecret);
        return this;
    }

    public final Configurator withActivity(Activity activity) {
        QUICK_CONFIGS.put(ConfigKeys.ACTIVITY, activity);
        return this;
    }

    public Configurator withJavascriptInterface(@NonNull String name) {
        QUICK_CONFIGS.put(ConfigKeys.JAVASCRIPT_INTERFACE, name);
        return this;
    }
    public static  void  put(Object key, Object value){
         QUICK_CONFIGS.put(key,value);
    }


  /*  public Configurator withWebEvent(@NonNull String name, @NonNull Event event) {
        final EventManager manager = EventManager.getInstance();
        manager.addEvent(name, event);
        return this;
    }*/

    private void checkConfiguration() {
        final boolean isReady = (boolean) QUICK_CONFIGS.get(ConfigKeys.CONFIG_READY);
        if (!isReady) {
            throw new RuntimeException("Configuration is not ready,call configure");
        }
    }

    @SuppressWarnings("unchecked")
    public final <T> T getConfiguration(Object key) {
        checkConfiguration();
        final Object value = QUICK_CONFIGS.get(key);
        if (value == null) {
            if(ConfigKeys.API_HOST.name().equals(key.toString())){
                return null;
            }
            throw new NullPointerException(key.toString() + " IS NULL");
        }
        return (T) QUICK_CONFIGS.get(key);
    }

}
